<?php
namespace app\common\model;

use app\common\lib\SqlEasy;
use mindplay\annotations\Annotations;
use think\Db;
use think\Model;

/**
 * 插件数据库操作
 */
class PluginDbTableModel extends Model
{
    /**
     * 读取安装模块的表信息
     * @param  $[symbol] [模块标识]
     * return true 安装成功  false 安装失败
     */
    public function installDataTable($symbol)
    {
        $result     = true;
        $directorys = $this->getDataPathFile($symbol);

        if (false === $directorys) {
            return ['error' => false, 'message' => '目录不存在，模块：' . $symbol . "，检查模块目录下是否存在目录：data"];
        } else if (is_array($directorys) && empty($directorys)) {
            return true;
        }
        $flag    = true;
        $sqlEasy = new SqlEasy();
        foreach ($directorys as $key => $value) {
            $file   = file_get_contents($value);
            $result = $sqlEasy->sqlExecute($file);
            if (isset($result['error'])) {
                break;
            }
        }
        return $result;
    }
    /**
     * 数据表卸载
     */
    public function uninstallDataTable($symbol)
    {
        $directorys = $this->getDataPathFile($symbol, 'sql', true);
        if (!empty($directorys)) {
            $dropTableSql = " DROP TABLE IF EXISTS ";
            $dropTableSql = $dropTableSql . implode(',', $directorys);
            Db::execute($dropTableSql);
        }
        return true;
    }
    /**
     * 检测需求表，需求模块是否存在
     * retutn  true / 1 存在   0不存在
     *
     */
    public function chechModuleAndTableIsExists($symbol)
    {
        $config = getModuleConfig($symbol, "data", "config.php");
        if (empty($config) || !is_array($config)) {
            return true;
            //配置不存在
        }
        $flag = 1;
        foreach ($config as $key => $value) {
            $tableNames = array_keys($value);
            $res        = $this->checkConfig($key, $tableNames);
            if (!$res) {
                $flag = 0;
                break;
            }
        }
        return $flag;
    }
    /**
     * 检查配置
     */
    private function checkConfig($moduleSymbol, $tableNames)
    {
        $status = 1;
        foreach ($tableNames as $key => $value) {
            $tableFile = PLUGINS_PATH . cmf_parse_name($moduleSymbol) . '/data' . '/' . $value . '.sql';
            if (!file_exists($tableFile)) {
                $status = 0;
                break;
                //模块不存在
            }
        }
        return $status;
    }
    /**
     * 获取文件
     * @param      $symbol string 模块标识
     * @param   $suffix string 文件后缀
     * @param      $getFileName  true 获取文件名，不带路径不带文件后缀    false 获取带路径 带后缀的文件名
     * @return [type]       [description]
     */
    public function getDataPathFile($symbol = '', $suffix = 'sql', $getFileName = false)
    {
        $sqlFileDirectory = PLUGINS_PATH . cmf_parse_name($symbol) . '/data';
        if (!file_exists($sqlFileDirectory)) {
            return false;
        }
        $directorys = scandir($sqlFileDirectory);
        $directorys = array_diff($directorys, ['.', '..']);
        if (empty($directorys)) {
            return [];
        }
        $pattern   = "/^(.*?)\." . $suffix . "$/i";
        $fileNames = [];
        foreach ($directorys as $key => $value) {
            if (preg_match($pattern, $value, $result) && isset($result[0])) {
                if ($getFileName) {
                    $fileNames[] = preg_replace("/\." . $suffix . "$/", '', $result[0]);
                } else {
                    $fileNames[] = $sqlFileDirectory . "/" . $result[0];
                }
            }
        }
        return $fileNames;
    }
    /**
     * 检查所有模块名字
     */
    public function checkModuleInfo($dir)
    {
        $dir                                       = cmf_parse_name($dir);
        $result                                    = true;
        $moduleInfoList                            = [];
        Annotations::$config['cache']              = false;
        $annotationManager                         = Annotations::getManager();
        $annotationManager->registry['pluginInfo'] = 'app\admin\annotation\PluginInfoAnnotation';
        $moduleName                                = cmf_parse_name($dir, 1);
        $class                                     = "\plugins\\$dir\\$moduleName" . "Plugin";
        if (!class_exists($class)) {
            return ['error' => false, 'message' => '类不存在：' . $class];
        }
        $infoList = Annotations::ofClass($class, '@pluginInfo');
        if (!empty($infoList)) {
            $list = $infoList[0];
            if (is_object($list)) {
                $list = (array) $list;
            }
            if (!isset($list['symbol']) || cmf_parse_name($dir) != cmf_parse_name($list['symbol'])) {
                $result = ['error' => false, 'message' => '@pluginInfo信息配置错误，模块名称：' . $dir];
            }
        }
        return $result;
    }
    /**
     * 检查所需模块是否存在 针对 config/demand.json中个需求配置
     */
    public function checkDemandModuleIsExists($pluginName)
    {
        //读取需求配置
        $config = getModuleConfig($pluginName, "config", "demand.json");
        $config = json_decode($config, true);
        if (empty($config) || !is_array($config)) {
            //配置不存在
            return true;
        }
        foreach ($config as $key => $value) {
            $demandSymbol = $value['demandSymbol'];
            $demandName   = $value['demandName'];
            $demandModule = PLUGINS_PATH . cmf_parse_name($demandSymbol) . DS . cmf_parse_name($demandSymbol, 1) . 'Plugin.php';
            if (!file_exists($demandModule)) {
                return ['status' => false, 'message' => '此模块正常运行所需模块:' . $demandName . '(' . $demandSymbol . ')不存在,请检查!'];
            }
        }
        return true;
    }
    //循环删除目录和文件函数
    public function delDirAndFile($dirName)
    {
        if (is_file($dirName)) {
            unlink($dirName);
            return true;
        }
        if ($handle = opendir("$dirName")) {
            while (false !== ($item = readdir($handle))) {
                if ($item != "." && $item != "..") {
                    $itemPath = "$dirName/$item";
                    //$itemPath = mb_convert_encoding ( "$dirName/$item" , 'gbk' , 'utf-8'  );
                    if (is_dir($itemPath)) {
                        $this->delDirAndFile($itemPath);
                    } else {
                        if (unlink($itemPath));
                    }
                }
            }
            closedir($handle);
            if (rmdir($dirName)) {
                return true;
            }
        }
    }
}
